package com.ptu.spzx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ptu.spzx.common.PageResult;
import com.ptu.spzx.common.exception.ptuException;
import com.ptu.spzx.domain.Delete.DeleteIds;
import com.ptu.spzx.domain.Message.Message;
import com.ptu.spzx.domain.Message.dto.MessageInsertDTO;
import com.ptu.spzx.domain.Message.dto.MessageQueryDTO;
import com.ptu.spzx.domain.Message.dto.MessageTeacherBatchQueryNoticeDTO;
import com.ptu.spzx.domain.Message.dto.MessageUpdateDTO;
import com.ptu.spzx.domain.Message.exceptions.DataNotFoundException;
import com.ptu.spzx.domain.Message.vo.StuCheckMessageVO;
import com.ptu.spzx.domain.Stu.StuMessage;
import com.ptu.spzx.mapper.MessageMapper;
import com.ptu.spzx.mapper.StuMessageMapper;
import com.ptu.spzx.model.vo.common.ResultCodeEnum;
import com.ptu.spzx.service.IMessageService;
import com.ptu.spzx.utils.BeanCopyUtils;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static io.lettuce.core.pubsub.PubSubOutput.Type.message;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author YT
 * @since 2024-01-28
 */
@Service
@Slf4j
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements IMessageService {
    @Autowired
    MessageMapper messageMapper;
    @Autowired
    StuMessageMapper stuMessageMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(MessageInsertDTO insertDTO) {
        String noticeTitle = insertDTO.getNoticeTitle();
        String noticeContext = insertDTO.getNoticeContext();
        if (insertDTO.getBelongCourseId() == null || noticeContext.isEmpty() || noticeTitle.isEmpty()) {
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        Message message = BeanCopyUtils.copyBean(insertDTO, Message.class);
        // 创建通知
        messageMapper.insert(message);
        // 关联表格
        if (insertDTO.getStuIds() != null) {
            for (String id : insertDTO.getStuIds()) {
                stuMessageMapper.insert(new StuMessage(message.getNoticeId(), id));
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(MessageUpdateDTO updateDTO) {
        if (updateDTO.getNoticeId() == null) {
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        List<String> stuIds = updateDTO.getStuIds();
        Message message = BeanCopyUtils.copyBean(updateDTO, Message.class);
        messageMapper.updateById(message);
        if(stuIds!=null){
            LambdaQueryWrapper<StuMessage> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(StuMessage::getNoticeId, updateDTO.getNoticeId());
            stuMessageMapper.delete(lambdaQueryWrapper);
            for (String stuId : stuIds) {
                StuMessage stuMessage = new StuMessage();
                stuMessage.setNoticeId(updateDTO.getNoticeId());
                stuMessage.setStuId(stuId);
                stuMessageMapper.insert(stuMessage);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByIds(DeleteIds deleteIds) {
        List<Long> ids = deleteIds.getIds();
        if (ids == null || ids.size() == 0) {
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        // 删除message表中数据
        messageMapper.deleteBatchIds(ids);
        // 删除stuMessage表中数据
        for (Long id : ids) {
            stuMessageMapper.deleteByNoticeId(id);
        }
    }


    @Override
    public PageInfo<Message> batchQueryByTeacher(Integer pageNumber, Integer pageSize, MessageTeacherBatchQueryNoticeDTO queryDTO) {
        String creator = queryDTO.getCreator();
        Long belongCourseId = queryDTO.getBelongCourseId();
        if (creator.isEmpty()||creator==null|| belongCourseId == null) {
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        Integer noticeType = queryDTO.getNoticeType();
        Long examId = queryDTO.getExamId();
        LambdaQueryWrapper<Message> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Message::getCreator, creator)
                .eq(Message::getBelongCourseId, belongCourseId)
                .eq(noticeType != null, Message::getNoticeType, noticeType)
                .eq(examId != null, Message::getExamId, examId);
        PageHelper.startPage(pageNumber, pageSize);
        List<Message> messages = messageMapper.selectList(lambdaQueryWrapper);
        PageInfo<Message> pageInfo = new PageInfo<>(messages);
        return pageInfo;
    }

    @Override
    public StuCheckMessageVO stuChekMessage(Long stuId, Long noticeId) {
        // 首先确定表格中有关联   -   查询，不存在就抛出异常
        Long id = stuMessageMapper.checkNotice(stuId, noticeId);
        if (id == null) {
            throw new ptuException(ResultCodeEnum.DATA_NOT_EXIST);
        }

        // 将stu_message表中isRead置1
        stuMessageMapper.updateReadTrue(id);

        // 拿到指定数据，将message转化成vo
        Message message = messageMapper.selectById(noticeId);
        return convertToCheckMessageVO(message);
    }

    @Override
    public String getReadNum(Long noticeId) {
        // 异常传参处理
        if (noticeId == null) {
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        // 查询指定noticeId的总人数
        Long allNum = stuMessageMapper.countByNoticeId(noticeId);
        // 查询已读人数
        Long isReadNum = stuMessageMapper.countIsRead(noticeId);
        // 将结果转化为字符串
        return isReadNum + "/" + allNum;
    }

    @Override
    public PageInfo<Message> batchQuery(Integer pageNumber, Integer pageSize, MessageQueryDTO queryDTO) {
        String stuId = queryDTO.getStuId();
        if (stuId.isEmpty()) {
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        List<Long> noticeIds = stuMessageMapper.selectByStuId(stuId);
        Long belongCourseId = queryDTO.getBelongCourseId();
        Integer noticeType = queryDTO.getNoticeType();
        Long examId = queryDTO.getExamId();
        LambdaQueryWrapper<Message> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(belongCourseId != null, Message::getBelongCourseId, belongCourseId)
                .eq(noticeType != null, Message::getNoticeType, noticeType)
                .eq(examId != null, Message::getExamId, examId)
                .in(Message::getNoticeId, noticeIds);
        PageHelper.startPage(pageNumber, pageSize);
        List<Message> messages = messageMapper.selectList(lambdaQueryWrapper);
        PageInfo<Message> messagePageInfo = new PageInfo<>(messages);
        return messagePageInfo;
    }

    private StuCheckMessageVO convertToCheckMessageVO(Message message) {
        StuCheckMessageVO checkVO = new StuCheckMessageVO();
        checkVO.setBelongCourseId(message.getBelongCourseId());
        checkVO.setExamId(message.getExamId());
        checkVO.setNoticeTitle(message.getNoticeTitle());
        checkVO.setNoticeContext(message.getNoticeContext());
        checkVO.setNoticeType(message.getNoticeType());
        checkVO.setCreator(message.getCreator());
        checkVO.setCreateTime(message.getCreateTime());
        return checkVO;
    }

}
